package com.mdlaser.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mdlaser.dto.LockedOrder;
import com.mdlaser.dto.OrderDetail;
import com.mdlaser.dto.OrdersWishesDto;
import com.mdlaser.entity.OrdersWishes;
import com.mdlaser.entity.WishLanguage;
import com.mdlaser.entity.WishType;
import com.mdlaser.enums.OrderStatusType;
import com.mdlaser.mapper.OrdersWishesMapper;
import com.mdlaser.service.IOrderConsumer;
import com.mdlaser.service.IOrdersWishesService;
import com.mdlaser.service.IWishLanguageService;
import com.mdlaser.service.IWishTypeService;
import com.mdlaser.sys.entity.User;
import com.mdlaser.sys.service.IUserService;
import com.mdlaser.util.UserUtil;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author mdlaser
 * @since 2024-05-16
 */
@Service
@Slf4j
public class OrdersWishesServiceImpl extends ServiceImpl<OrdersWishesMapper, OrdersWishes> implements IOrdersWishesService {
    /**
     * 商户号
     */
    @Value("${wx.pay.merchantId:1674871603}")
    public String merchantId;

    @Value("${wx.pay.appId:wx0ada05ee408885ae}")
    public String appId;

    /**
     * 商户API私钥路径
     */
    @Value("${wx.pay.privateKeyPath:/apppay/apiclient_key.pem}")
    public String privateKeyPath;

    /**
     * 商户证书序列号
     */
    @Value("${wx.pay.merchantSerialNumber:586285A0E3F2BC3A452D09AE755FE8D2948A3C13}")
    public String merchantSerialNumber;

    /**
     * 商户APIV3密钥
     */
    @Value("${wx.pay.apiV3Key:355d57904154152f3f951d1add80b4c6}")
    public String apiV3Key;

    @Value("${serverDomain:null}")
    String serverDomain;

    @Autowired
    IUserService userService;
    @Autowired
    IOrdersWishesService ordersWishesService;
    @Autowired
    IWishLanguageService wishLanguageService;

    @Autowired
    IWishTypeService wishTypeService;
    Config vxConfig;

    @PostConstruct
    private void initConfig() {
        vxConfig = new RSAAutoCertificateConfig.Builder()
                .merchantId(merchantId)
                // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
                .privateKeyFromPath(privateKeyPath)
                .merchantSerialNumber(merchantSerialNumber)
                .apiV3Key(apiV3Key)
                .build();

    }

    @Override
    public OrderDetail getOrderDetailById(String orderId) {
        OrdersWishes ordersWishes = ordersWishesService.getBaseMapper().selectById(orderId);
        if (ordersWishes == null) {
            throw new RuntimeException("订单不存在！");
        }
        String languageDetail = wishLanguageService.getLanguageDetailById(ordersWishes.getLanguageId());
        OrderDetail orderDetail = new OrderDetail();
        BeanUtils.copyProperties(ordersWishes, orderDetail);
        orderDetail.setLanguageDetail(languageDetail);
        return orderDetail;
    }

    @Override
    public List<OrderDetail> getList() {
        LambdaQueryWrapper<OrdersWishes> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(OrdersWishes::getApptDate);
        ArrayList<OrderDetail> OrderDetails = new ArrayList<>();
        List<OrdersWishes> ordersWishes = ordersWishesService.getBaseMapper().selectList(queryWrapper);
        ordersWishes.forEach(o -> {
            OrderDetail orderDetail = getOrderDetail(o);
            OrderDetails.add(orderDetail);
        });
        return OrderDetails;
    }

    @Override
    public List<OrderDetail> getMyOrders() {
        StpUtil.checkLogin();
        User currentUser = UserUtil.getCurrentUser();
        LambdaQueryWrapper<OrdersWishes> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrdersWishes::getUserId, currentUser.getId());
        queryWrapper.orderByDesc(OrdersWishes::getApptDate);
        ArrayList<OrderDetail> OrderDetails = new ArrayList<>();
        List<OrdersWishes> ordersWishes = ordersWishesService.getBaseMapper().selectList(queryWrapper);
        ordersWishes.forEach(o -> {
            OrderDetail orderDetail = getOrderDetail(o);
            OrderDetails.add(orderDetail);
        });
        return OrderDetails;
    }

    private OrderDetail getOrderDetail(OrdersWishes o) {
        OrderDetail orderDetail = new OrderDetail();
        BeanUtils.copyProperties(o, orderDetail);
        String language = wishLanguageService.getLanguageDetailById(orderDetail.getLanguageId());
        orderDetail.setLanguageDetail(language);
        return orderDetail;
    }

    @Override
    public OrderDetail post(OrdersWishesDto ordersWishesDto) {
        OrdersWishes ordersWishes = new OrdersWishes();
        User currentUser = UserUtil.getCurrentUser();
        BeanUtils.copyProperties(ordersWishesDto, ordersWishes);
        String id = currentUser.getId();
        ordersWishes.setUserId(id);
        ordersWishes.setOrderStatus(OrderStatusType.INIT.getId());
        ordersWishesService.getBaseMapper().insert(ordersWishes);
        return this.getOrderDetail(ordersWishes);
    }


    @Override
    public PrepayWithRequestPaymentResponse createWxOrder(String orderId) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String currentUserId = UserUtil.getCurrentUserId();
        OrdersWishes ordersWishes = ordersWishesService.getBaseMapper().selectById(orderId);


        if (ordersWishes == null) {
            throw new RuntimeException("订单不存在，请检查！");
        }
        Date apptDate = ordersWishes.getApptDate();
        List<Integer> disableAppTime = this.getDisableAppTime(apptDate, ordersWishes.getLanguageId());
        Calendar instance = Calendar.getInstance();
        instance.setTime(apptDate);
        Integer hour = instance.get(Calendar.HOUR_OF_DAY);
        if (disableAppTime.contains(hour)) {
            throw new RuntimeException("当前预约时段节目已满，请重新发起预约！");
        }
        if (!Objects.equals(currentUserId, ordersWishes.getUserId())) {
            throw new RuntimeException("无法支付他人订单！");
        }
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(vxConfig).build();
        Float paymentAmount = ordersWishes.getPaymentAmount();
        // 跟之前下单示例一样，填充预下单参数
        PrepayRequest payRequest = new PrepayRequest();
        payRequest.setAppid(appId);
        payRequest.setMchid(merchantId);
        String vxOrderId = OrdersWishes.getVxOrderId(orderId);
        payRequest.setOutTradeNo(vxOrderId);
        Payer payer = new Payer();
        payer.setOpenid(currentUserId);
        payRequest.setPayer(payer);
        Amount amount = new Amount();
        amount.setTotal((int) (paymentAmount * 100));
        payRequest.setAmount(amount);
        String notifyUrl = serverDomain + "/orders-wishes/paySuccess";
        payRequest.setNotifyUrl(notifyUrl);
        payRequest.setDescription("名都激光");
        SceneInfo sceneInfo = new SceneInfo();
        sceneInfo.setPayerClientIp(getIp(request));
        payRequest.setSceneInfo(sceneInfo);

        return service.prepayWithRequestPayment(payRequest);
    }


    @Override
    public Refund refund(String orderId, String reason) {
        OrdersWishes ordersWishes = ordersWishesService.getBaseMapper().selectById(orderId);

        RefundService service = new RefundService.Builder().config(vxConfig).build();


        CreateRequest request = new CreateRequest();
        Float paymentAmount = ordersWishes.getPaymentAmount();
        String transactionId = ordersWishes.getTransactionId();
        AmountReq amountReq = new AmountReq();
        amountReq.setRefund((long) (paymentAmount * 100));
        amountReq.setTotal((long) (paymentAmount * 100));
        amountReq.setCurrency("CNY");
        String vxOrderId = OrdersWishes.getVxOrderId(orderId);
        request.setOutTradeNo(vxOrderId);
        String outRefundNo = OrdersWishes.getOutRefundNo(orderId);
        request.setOutRefundNo(outRefundNo);
        request.setTransactionId(transactionId);
        request.setReason(reason);
        request.setNotifyUrl(serverDomain + "/orders-wishes/refundSuccess");
        request.setAmount(amountReq);
        return service.create(request);

    }

    @Override
    public Object vxRefundSuccess(String requestBody) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String wechatSignature = request.getHeader("Wechatpay-Signature");
        String wechatPaySerial = request.getHeader("Wechatpay-Serial");
        String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
        String wechatTimestamp = request.getHeader("Wechatpay-Timestamp");
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatPaySerial)
                .nonce(wechatpayNonce)
                .signature(wechatSignature)
                .timestamp(wechatTimestamp)
                .body(requestBody)
                .build();
        NotificationParser parser = new NotificationParser((NotificationConfig) vxConfig);
        try {
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            RefundNotification refundNotification = parser.parse(requestParam, RefundNotification.class);
            log.info("微信平台回调解密成功，信息" + refundNotification);
            String transactionId = refundNotification.getTransactionId(); //vx订单号
            String outTradeNo = refundNotification.getOutTradeNo();
            String orderId = OrdersWishes.getOriginalId(outTradeNo);
            OrdersWishes ordersWishes = this.getBaseMapper().selectById(orderId);
            ordersWishes.setTransactionId(transactionId);
            ordersWishes.setOrderStatus(OrderStatusType.REFUND.getId());
            ordersWishes.setRefundTime(new Date());
            this.getBaseMapper().updateById(ordersWishes);
            orderConsumer.cancelConsumer(orderId);
        } catch (ValidationException e) {
            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
            log.error("验证签名失败", e);
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED);
        }

        // 处理成功，返回 200 OK 状态码
        return ResponseEntity.status(HttpStatus.OK);
    }


    @Override
    public List<Integer> getDisableAppTime(Date startTime, String languageId) {
        ArrayList<Integer> disableTime = new ArrayList<>();
        outerLoop:
        for (int i = 0; i <= 23; i++) {
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(startTime);
            startCalendar.set(Calendar.HOUR_OF_DAY, i);
            startCalendar.set(Calendar.MINUTE, 0);
            startCalendar.set(Calendar.SECOND, 0);

            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(startTime);
            endCalendar.set(Calendar.HOUR_OF_DAY, i + 1);
            endCalendar.set(Calendar.MINUTE, 0);
            endCalendar.set(Calendar.SECOND, 0);
            if (endCalendar.getTime().compareTo(new Date()) < 0) {
                disableTime.add(i);
                continue;
            }

            LambdaQueryWrapper<OrdersWishes> cancelWrapper = new LambdaQueryWrapper<>();
            cancelWrapper.ge(OrdersWishes::getStartTime, startCalendar.getTime());
            cancelWrapper.lt(OrdersWishes::getStartTime, endCalendar.getTime());
            cancelWrapper.eq(OrdersWishes::getOrderStatus, OrderStatusType.REFUND.getId());

            List<OrdersWishes> cancelOrdersWishes = this.getBaseMapper().selectList(cancelWrapper);
            for (OrdersWishes cancelOrdersWish : cancelOrdersWishes) {
                WishLanguage cancelLanguage = wishLanguageService.getBaseMapper().selectById(cancelOrdersWish.getLanguageId());
                WishLanguage targetLanguage = wishLanguageService.getBaseMapper().selectById(cancelOrdersWish.getLanguageId());
                if (Objects.equals(cancelLanguage.getDuration(), targetLanguage.getDuration()) &&
                        cancelOrdersWishes.get(0).getStartTime().compareTo(new Date()) > 0) {
                    LambdaQueryWrapper<OrdersWishes> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(OrdersWishes::getStartTime, cancelOrdersWish.getStartTime());
                    wrapper.eq(OrdersWishes::getOrderStatus, OrderStatusType.PAY.getId());
                    wrapper.orderByDesc(OrdersWishes::getStartTime);
                    List<OrdersWishes> ordersWishes = this.getBaseMapper().selectList(wrapper);
                    if (CollectionUtils.isEmpty(ordersWishes)) {
                        continue outerLoop;
                    }

                }
            }


            LambdaQueryWrapper<OrdersWishes> wrapper = new LambdaQueryWrapper<>();
            wrapper.ge(OrdersWishes::getStartTime, startCalendar.getTime());
            wrapper.lt(OrdersWishes::getStartTime, endCalendar.getTime());
            wrapper.eq(OrdersWishes::getOrderStatus, OrderStatusType.PAY.getId());
            wrapper.orderByDesc(OrdersWishes::getStartTime);
            List<OrdersWishes> ordersWishes = this.getBaseMapper().selectList(wrapper);
            WishLanguage language = wishLanguageService.getBaseMapper().selectById(languageId);
            Integer duration = language.getDuration();
            if (!CollectionUtils.isEmpty(ordersWishes)) {
                OrdersWishes lastOrder = ordersWishes.get(0);
                Date lastOrderTime = lastOrder.getStopTime();
                Calendar lastOrderCalendar = Calendar.getInstance();
                lastOrderCalendar.setTime(lastOrderTime);
                int minute = lastOrderCalendar.get(Calendar.MINUTE);
                if ((60 - minute) <= duration
                        || endCalendar.getTime().getTime() - new Date().getTime() <= duration * 1000) {
                    disableTime.add(i);
                }
            } else {
                if (endCalendar.getTime().getTime() - new Date().getTime() <= duration * 1000 * 60) {
                    disableTime.add(i);
                }
            }
        }
        return disableTime;
    }

    @Autowired
    IOrderConsumer orderConsumer;

    @Override
    public Object vxPayCallBack(String requestBody) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String wechatSignature = request.getHeader("Wechatpay-Signature");
        String wechatPaySerial = request.getHeader("Wechatpay-Serial");
        String wechatpayNonce = request.getHeader("Wechatpay-Nonce");
        String wechatTimestamp = request.getHeader("Wechatpay-Timestamp");
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatPaySerial)
                .nonce(wechatpayNonce)
                .signature(wechatSignature)
                .timestamp(wechatTimestamp)
                .body(requestBody)
                .build();

        NotificationParser parser = new NotificationParser((NotificationConfig) vxConfig);
        try {
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            log.info("微信平台回调解密成功，信息" + transaction);
            String transactionId = transaction.getTransactionId(); //vx订单号
            String outTradeNo = transaction.getOutTradeNo();
            String orderId = OrdersWishes.getOriginalId(outTradeNo);
            createPayOrder(transactionId, orderId);
        } catch (ValidationException e) {
            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
            log.error("验证签名失败", e);
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED);
        }
        // 处理成功，返回 200 OK 状态码
        return ResponseEntity.status(HttpStatus.OK);
    }

    @Override
    public synchronized void createPayOrder(String transactionId, String orderId) {
        Date currentDate = new Date();
        OrdersWishes payOrder = this.getBaseMapper().selectById(orderId);
        payOrder.setTransactionId(transactionId);
        payOrder.setPayTime(new Date());
        Date apptDate = payOrder.getApptDate();
        //先去看下有没有退款的单子，有退款的就填坑
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(apptDate);
        startCalendar.set(Calendar.MINUTE, 0);
        startCalendar.set(Calendar.SECOND, 0);

        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(apptDate);
        endCalendar.set(Calendar.MINUTE, 0);
        endCalendar.set(Calendar.SECOND, 0);
        endCalendar.add(Calendar.HOUR, 1);

        LambdaQueryWrapper<OrdersWishes> refundWrapper = new LambdaQueryWrapper<>();
        refundWrapper.ge(OrdersWishes::getStartTime, startCalendar.getTime());
        refundWrapper.lt(OrdersWishes::getStartTime, endCalendar.getTime());
        refundWrapper.eq(OrdersWishes::getOrderStatus, OrderStatusType.REFUND.getId());
        List<OrdersWishes> refundWishesList = this.getBaseMapper().selectList(refundWrapper);
        if (!CollectionUtils.isEmpty(refundWishesList) && apptDate.compareTo(currentDate) > 0) {
            for (OrdersWishes wishes : refundWishesList) {
                WishLanguage wishLanguage = this.wishLanguageService.getBaseMapper().selectById(wishes.getLanguageId());
                WishLanguage thisLanguage = this.wishLanguageService.getBaseMapper().selectById(wishes.getLanguageId());
                if (Objects.equals(wishLanguage.getDuration(), thisLanguage.getDuration())) {
                    LambdaQueryWrapper<OrdersWishes> verifyWrapper = new LambdaQueryWrapper<>();
                    verifyWrapper.eq(OrdersWishes::getOrderStatus, OrderStatusType.PAY.getId());
                    verifyWrapper.eq(OrdersWishes::getStartTime, wishes.getStartTime());
                    if (CollectionUtils.isEmpty(this.getBaseMapper().selectList(verifyWrapper))) {
                        payOrder.setStartTime(wishes.getStartTime());
                        payOrder.setStopTime(wishes.getStopTime());
                        payOrder.setOrderStatus(OrderStatusType.PAY.getId());
                        this.getBaseMapper().updateById(payOrder);
                        orderConsumer.startConsumer(orderId);
                        return;
                    }
                }
            }
        }

        LambdaQueryWrapper<OrdersWishes> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(OrdersWishes::getStartTime, startCalendar.getTime());
        wrapper.lt(OrdersWishes::getStartTime, endCalendar.getTime());
        wrapper.eq(OrdersWishes::getOrderStatus, OrderStatusType.PAY.getId());
        wrapper.orderByDesc(OrdersWishes::getStartTime);
        List<OrdersWishes> ordersWishesList = this.getBaseMapper().selectList(wrapper);

        Calendar allocatedTime;
        WishLanguage wishLanguage = this.wishLanguageService.getBaseMapper().selectById(payOrder.getLanguageId());

        //播放时间要比当前时间慢2分钟

        if (CollectionUtils.isEmpty(ordersWishesList)) {
            if (apptDate.compareTo(currentDate) <= 0) {
                Calendar currentCalendar = Calendar.getInstance();
                currentCalendar.setTime(currentDate);
                currentCalendar.add(Calendar.MINUTE, 2);
                currentCalendar.set(Calendar.SECOND, 0);
                allocatedTime = currentCalendar;
            } else {
                allocatedTime = startCalendar;
                allocatedTime.set(Calendar.MINUTE, 0);
            }
        } else {
            OrdersWishes lastWish = ordersWishesList.get(0);
            Date lastWishStopTime = lastWish.getStopTime();
            if (lastWishStopTime.compareTo(currentDate) >= 0) {
                allocatedTime = Calendar.getInstance();
                allocatedTime.setTime(lastWishStopTime);
                allocatedTime.add(Calendar.MINUTE, wishLanguage.getDuration());
            } else {
                Calendar currentCalendar = Calendar.getInstance();
                currentCalendar.setTime(currentDate);
                currentCalendar.add(Calendar.MINUTE, 2);
                currentCalendar.set(Calendar.SECOND, 0);
                allocatedTime = currentCalendar;
            }

        }

        payOrder.setStartTime(allocatedTime.getTime());

        allocatedTime.add(Calendar.MINUTE, wishLanguage.getDuration());
//        allocatedTime.add(Calendar.SECOND, 0);
        payOrder.setStopTime(allocatedTime.getTime());
        payOrder.setOrderStatus(OrderStatusType.PAY.getId());
        this.getBaseMapper().updateById(payOrder);
        orderConsumer.startConsumer(orderId);
    }

    @Override
    public List<LockedOrder> getLockOrder() {
        ArrayList<LockedOrder> lockedOrders = new ArrayList<>();
        LambdaQueryWrapper<OrdersWishes> wrapper = new LambdaQueryWrapper<>();
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.MINUTE, 30);
        Date time = instance.getTime();
        wrapper.ge(OrdersWishes::getStartTime, new Date());
        wrapper.le(OrdersWishes::getStartTime, time);
        wrapper.eq(OrdersWishes::getOrderStatus, OrderStatusType.PAY.getId());
        List<OrdersWishes> ordersWishes = this.getBaseMapper().selectList(wrapper);
        ordersWishes.forEach(o -> {
            WishLanguage wishLanguage = this.wishLanguageService.getBaseMapper().selectById(o.getLanguageId());
            WishType wishType = this.wishTypeService.getBaseMapper().selectById(wishLanguage.getWishId());
            LockedOrder lockedOrder = new LockedOrder();
            lockedOrder.setTask_id(o.getOrderId());
            lockedOrder.setStart_time(o.getStartTime());
            lockedOrder.setEnd_time(o.getStopTime());
            lockedOrder.setProgram_type(wishType.getWishType());
            lockedOrder.setProgram_type(wishType.getWishType());
            lockedOrder.setProgram_id(Integer.valueOf(wishLanguage.getProId()));
            lockedOrder.setSend(o.getApptUser());
            lockedOrder.setReceive(o.getApptRecipient());
            lockedOrders.add(lockedOrder);
        });
        return lockedOrders;
    }


    private static String getIp(HttpServletRequest request) {
        String ipAddress = request.getHeader("X-Forwarded-For");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        return "Client IP address: " + ipAddress.split(",")[0];
    }

}
